package com.naiterui.ehp.bs.doctor.controller;

import java.util.List;

import com.naiterui.ehp.bp.constants.SwaggerTag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bp.bo.esign.DigitalCertificateBO;
import com.naiterui.ehp.bp.bo.esign.EsignNoSecretBO;
import com.naiterui.ehp.bp.bo.esign.PreSignResultBO;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.support.exception.BaseExceptionCodes;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.support.exception.PublicService;
import com.naiterui.ehp.bp.support.exception.ResponseVO;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.bs.doctor.exception.ExceptionCodes;
import com.naiterui.ehp.bs.doctor.service.user.IEsignUserService;
import com.naiterui.ehp.bs.doctor.utils.SealImageUtil;
import com.naiterui.ehp.bs.doctor.vo.sign.WillTypeVO;

import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

/**
 * @Description 电子签名先关接口
 * @Author gongbaoqiang
 * @Date 2020/6/8 3:46 PM
 */
@Slf4j
@Api(tags = {SwaggerTag.DOCTOR + SwaggerTag.CA_ESIGN})
@RequestMapping("ad/esign/user")
@RestController
public class AdDoctorEsignUserController {
    @Autowired
    private IEsignUserService esignService;

    /**
     * <获取实名认证验证码>
     * @param doctorId
     * @return
     * @throws BusinessException
     */
    @ResponseBody
    @PostMapping("realname/code")
    @ApiOperation(value = "获取实名认证验证码", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生id", required = true, dataType = "long") })
    public ResponseVO<Void> realnameCode(Long doctorId) throws BusinessException {

        log.info("获取实名认证验证码 请求参数：doctorId = [{}]", doctorId);

        esignService.getRealnameCode(doctorId);

        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);

    }

    /**
     * <获取实名认证验证码>
     * @param doctorId
     * @return
     * @throws BusinessException
     */
    @ResponseBody
    @PostMapping("realname/check")
    @ApiOperation(value = "验证实名认证验证码", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生id", required = true, dataType = "long"),
            @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "string") })
    public ResponseVO<Void> realnameCheck(Long doctorId, String code) throws BusinessException {

        log.info("验证实名认证验证码 请求参数：doctorId = [{}], code={}", doctorId, code);

        esignService.checkRealnameCode(doctorId, code);

        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS, ConfigUtil.getString("doctor.auth.success"),
            null);

    }

    /**
     * <获取签署方式列表>
     * @return
     * @throws BusinessException
     */
    @PostMapping("will/types")
    @ApiOperation(value = "获取签署方式列表", httpMethod = "POST")
    public ResponseVO<List<WillTypeVO>> willTypes(Long doctorId) throws BusinessException {

        log.info("医生获取签署方式列表：doctorId={}", doctorId);

        return PublicService.returnResponseVO(esignService.getWillTypes(doctorId));

    }

    /**
     * <保存医生意愿签署方式>
     * @param doctorId
     * @return
     * @throws BusinessException
     */
    @PostMapping("will/type/save")
    @ApiOperation(value = "保存医生意愿签署方式", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生id", required = true, dataType = "long"),
            @ApiImplicitParam(name = "willType", value = "签署方式", required = true, dataType = "string") })
    public ResponseVO<Void> saveWillType(Long doctorId, String willType) throws BusinessException {

        log.info("保存医生意愿签署方式 请求参数：doctorId = [{}], willType={}", doctorId, willType);

        esignService.updateWillType(doctorId, willType);

        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);

    }


    /**
     * <设置签名密码>
     * @param doctorId
     * @return
     * @throws BusinessException
     */
    @PostMapping("password/set")
    @ApiOperation(value = "设置签名密码", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生id", required = true, dataType = "long"),
            @ApiImplicitParam(name = "passwd", value = "签名密码", required = true, dataType = "string"),
            @ApiImplicitParam(name = "code", value = "短信验证码", required = true, dataType = "string"),
    })
    public ResponseVO<Void> setPassword(Long doctorId, String passwd, String code) throws BusinessException {

        log.info("获取实名认证验证码 请求参数：doctorId = [{}], passwd={}", doctorId, passwd);

        esignService.updatePassword(doctorId, passwd, code);

        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);

    }


    /**
     * <是否已设置签名密码>
     * @param doctorId
     * @return
     * @throws BusinessException
     */
    @PostMapping("password/set/status")
    @ApiOperation(value = "是否已设置签名密码", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生id", required = true, dataType = "long")
    })
    public ResponseVO<Boolean> passwordStatus(Long doctorId) throws BusinessException {

        log.info("医生是否已设置签名密码 请求参数：doctorId = [{}]", doctorId);

        return PublicService.returnResponseVO(esignService.passwordStatus(doctorId));

    }

    @GetMapping("/getNoSecret")
    @ApiOperation("获取免密状态")
    @ApiImplicitParams({@ApiImplicitParam(name = "doctorId", value = "医生id", required = true, dataType = "long")})
    public ResponseVO<EsignNoSecretBO> getNoSecret(Long doctorId) throws BusinessException {
        log.info("获取免密状态：doctorId={}", doctorId);
        EsignNoSecretBO noSecretBO = esignService.getNoSecretByDoctorId(doctorId);
        log.info("获取免密结果：{}", JSONUtil.toJsonStr(noSecretBO));
        return PublicService.returnResponseVO(noSecretBO);
    }

    @PostMapping("/preNoSecret")
    @ApiOperation("免密预签署")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生id", required = true, dataType = "long")
    })
    public ResponseVO<PreSignResultBO> preNoSecret(Long doctorId) throws BusinessException {
        log.info("免密预签署：doctorId={}", doctorId);
        return PublicService.returnResponseVO(esignService.preNoSecret(doctorId));
    }

    @PostMapping("/setNoSecret")
    @ApiOperation("设置免密")
    @ApiImplicitParams({@ApiImplicitParam(name = "doctorId", value = "医生id", required = true, dataType = "long"),
        @ApiImplicitParam(name = "noSecret", value = "免密 true开通 false关闭", required = true, dataType = "boolean"),
        @ApiImplicitParam(name = "authPwd", value = "签名密码, noSecret为false可以为空", dataType = "string"),
        @ApiImplicitParam(name = "uniqueId", value = "唯一标识, noSecret为false可以为空", dataType = "string")
    })
    public ResponseVO<Void> setNoSecret(Long doctorId, Boolean noSecret, String authPwd, String uniqueId)
        throws BusinessException {
        log.info("设置免密：doctorId={}, authPwd={}", doctorId, authPwd);
        if (doctorId == null || noSecret == null) {
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        if (noSecret && uniqueId == null) {
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        esignService.setNoSecret(doctorId, noSecret, authPwd, uniqueId);
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }

    @PostMapping("/notRemind")
    @ApiOperation("7天不提醒")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "doctorId", value = "医生id", required = true, dataType = "long")
    })
    public ResponseVO<Void> notRemind(Long doctorId) throws BusinessException {
        log.info("免密7天不提醒：doctorId={}", doctorId);
        if (doctorId == null) {
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        // 存入7天不提醒
        RedisUtil.valueOps().setString(CommonConstant.DR_NO_SECRET_REMIND + doctorId, "1", 7 * 24 * 3600);
        return PublicService.returnResponseVO(ExceptionCodes.SUCCESS);
    }

    @GetMapping("/getDigitalCertificate")
    @ApiOperation("获取医生数字证书")
    @ApiImplicitParam(name = "doctorId", value = "医生id", required = true, dataType = "long")
    private DigitalCertificateBO getDigitalCertificate(@RequestParam Long doctorId) throws BusinessException {
        return esignService.getDigitalCertificate(doctorId);
    }

    /**
     * 生成签章图
     *
     * @param doctorId
     * @param name
     * @return
     */
    @GetMapping("seal/generation")
    @ApiOperation(value = "生成姓名签章图base64")
    @ApiImplicitParams({@ApiImplicitParam(name = "doctorId", value = "医生id", required = true, dataType = "long"),
        @ApiImplicitParam(name = "name", value = "姓名", required = true, dataType = "String")})
    public ResponseVO<String> sealGeneration(Long doctorId, String name) {
        log.info("医生生成姓名签章 请求参数：doctorId = [{}], name = [{}]", doctorId, name);
        return PublicService.returnResponseVO(SealImageUtil.graphicsNameSealGeneration(name));
    }
}